package com.bluedot.service;

import com.bluedot.controller.DistributeClass;

import com.bluedot.pojo.pack.PreMappedStatement;
import com.bluedot.pojo.pack.ResultEntity;
import com.bluedot.pojo.vo.AlgorithmHotNumberVO;
import com.bluedot.pojo.vo.AlgorithmVO;
import com.bluedot.utils.ResourceUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

public class AlgorithmService extends DistributeClass {
    private UtilTool util;
    private AlgorithmVO algorithmVO=new AlgorithmVO();
    private AlgorithmHotNumberVO algorithmHotNumberVO=new AlgorithmHotNumberVO();


    public AlgorithmService(PreMappedStatement preMappedStatement) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        super(preMappedStatement);
        this.util = new UtilTool();
        String[] split = preMappedStatement.getMethodType().split("/");
        switch (split[split.length - 1]) {
            case "queryAllAlgorithm":
                List<Object> objects = queryAllAlgorithm();
                getResponseQueue().add(ResultEntity.successWithData(objects));
                break;
            case "queryByUserId":
                List<Object> objects1 = queryByUserId();
                getResponseQueue().add(ResultEntity.successWithData(objects1));
                break;
            case "deleteById":
                deleteById();
                break;
            case "queryDeleteAlgorithm":
                List<Object> objects2 = queryDeleteAlgorithm();
                getResponseQueue().add(ResultEntity.successWithData(objects2));
                break;
            case "deleteBackAlgorithm":
                deleteBackAlgorithmAndFile();
                break;
            case "upload":
                try {
                    upload(preMappedStatement.getRequest());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case "queryHotNumberA":
                List<Object> objectsA = queryHotNumberA();
                getResponseQueue().add(ResultEntity.successWithData(objectsA));
                break;
            case "queryHotNumberB":
                List<Object> objectsB = queryHotNumberB();
                getResponseQueue().add(ResultEntity.successWithData(objectsB));
                break;
            case "queryHotNumberC":
                List<Object> objectsC = queryHotNumberC();
                getResponseQueue().add(ResultEntity.successWithData(objectsC));
                break;

            case "deleteBackById":
                deleteBackById();
                break;
            case "hotNumberAdd":
                hotNumberAdd();
                break;
            case "checkAlgorithm":
                checkAlgorithm();
                break;
            case "rejectAlgorithm":
                rejectAlgorithm();
                break;
            default:
                break;
        }
    }

    /**
     * 管理员查询未审核开源的算法
     * @return
     */
    private List<Object> queryAllAlgorithm() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        algorithmVO.setAlgorithmDelete(0);//算法未被删除
        algorithmVO.setAlgorithmState(1);//开源算法
        algorithmVO.setAlgorithmCheck(1);//审核未通过
        List<Object> queryAllAlgorithm = util.query(new PreMappedStatement(util.QUERY,algorithmVO));
        return queryAllAlgorithm;
    }

    /**
     * 管理员审核算法
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private void checkAlgorithm() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        algorithmVO.setAlgorithmCheck(0);
        util.update(new PreMappedStatement(util.UPDATE,algorithmVO));
    }

    /**
     * 管理员驳回算法
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private void rejectAlgorithm() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }

        util.delete(new PreMappedStatement(util.DELETE,algorithmVO));
    }

    /**
     * 用户查询自己所有算法
     * @return
     */
    private List<Object> queryByUserId() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        algorithmVO.setAlgorithmDelete(0);//未被删除
        algorithmVO.setAlgorithmCheck(0);//管理员审核通过
        List<Object> query = util.query(new PreMappedStatement(util.QUERY, algorithmVO));
        return query;
    }


    /**
     * 用户根据id删除算法(逻辑删除)
     */
    private void deleteById() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        algorithmVO.setAlgorithmDelete(1);
        util.update(new PreMappedStatement(util.UPDATE,algorithmVO));
    }

    /**
     * 用户查询回收站算法
     */
    private List<Object> queryDeleteAlgorithm() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        algorithmVO.setAlgorithmDelete(1);//已经被删除
        List<Object> query = util.query(new PreMappedStatement(util.QUERY, algorithmVO));
        return query;
    }

    /**
     *用户还原回收站算法
     */
    private void deleteBackById() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        algorithmVO.setAlgorithmDelete(0);
        util.update(new PreMappedStatement(util.UPDATE,algorithmVO));
    }

    /**
     * 用户删除回收站算法,彻底删除
     */
    private void deleteBackAlgorithm() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析JSON数据
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }

        util.delete(new PreMappedStatement(util.DELETE, algorithmVO));
    }

    /**
     * 用户删除算法并且删除文件
     * @Time 2022.10.28
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private void deleteBackAlgorithmAndFile() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        String data1 = (String) preMappedStatement.getData();
        // 1.解析JSON数据
        if(data1 != null && (data1).length()>0){
            String data = data1;
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            throw new RuntimeException("输入数据有误");
        }
        // 2.获取算法文件路径
        List<Object> query = util.query(new PreMappedStatement<>(UtilTool.QUERY, algorithmVO));
        if (query == null || query.size() <= 0){
            // 没查出对应算法
            throw new RuntimeException("没有对应算法");
        }
        AlgorithmVO algorithm = (AlgorithmVO) query.get(0);
        String algorithmUrl = algorithm.getAlgorithmUrl();
        // 3.删除数据库数据
        boolean delete = util.delete(new PreMappedStatement(UtilTool.DELETE, algorithmVO));
        if (!delete){
            // 删除失败
            throw new RuntimeException("删除失败");
        }
        // 4.删除文件
        File file = new File(algorithmUrl);
        if (file == null||!file.exists()){
            // 算法文件不存在
            throw new RuntimeException("文件不存在");
        }
        boolean flag = file.delete();
        if (!flag){
            throw new RuntimeException("文件删除失败");
        }
    }
    /**
     * 用户上传算法
     * @param request
     * @throws IOException
     */
    private void upload(HttpServletRequest request) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        // 解析form表单数据
        String algorithmName = (String) request.getParameter("algorithmName");
        String algorithmDescribe = (String) request.getParameter("algorithmDescribe");
        String userId = (String) request.getParameter("userId");
        Integer algorithmState = (Integer.valueOf(request.getParameter("algorithmState"))) ;
        String algorithmType = request.getParameter("algorithmType");
        String algorithmExe = (String) request.getParameter("algorithmExe");
        String format=null;
        if(algorithmExe.equals("c")){
            format=".exe";
        }else if(algorithmExe.equals("java")){
            format=".class";
        }else if(algorithmExe.equals("python")){
            format=".py";
        }else if(algorithmExe.equals("c++")){
            format=".exe";
        }else {
            throw new RuntimeException("没有对应的语言类型算法");
        }

        InputStream file = preMappedStatement.getFile();
        String name= UUID.randomUUID().toString().replace("-", "").substring(0,5)+"_"+algorithmName;


        String path = ResourceUtil.ALGORITHM_URL +name+format;
        byte[] bytes = new byte[1024];
        OutputStream fileOutputStream = new FileOutputStream(path);
        int readCount;
        while((readCount = file.read(bytes)) != -1) {
            fileOutputStream.write(bytes,0,readCount);
        }

        if(fileOutputStream!=null){
            fileOutputStream.flush();
            fileOutputStream.close();
        }


        Integer testNumber=1;//测试参数
        boolean flagBox = testBox(path,testNumber);
        if(true){
            //通过黑盒测试,将算法相关数据保存到数据库
            algorithmVO.setAlgorithmName(algorithmName);//算法名称
            algorithmVO.setHotNumber(0);//算法使用量
            algorithmVO.setAlgorithmDescribe(algorithmDescribe);//算法描述
            algorithmVO.setAlgorithmUrl(path);//算法存放路径
            algorithmVO.setUserId(userId);//上传算法用户id
            algorithmVO.setAlgorithmState(algorithmState);//算法状态,0私有,1开源
            if(algorithmState==0){
                algorithmVO.setAlgorithmCheck(0);//私有算法,默认通过了为0,表示管理员审核通过
            }else {
                algorithmVO.setAlgorithmCheck(1);//公有算法,默认未通过1,等待管理员审核
            }
            algorithmVO.setAlgorithmDelete(0);//算法是否删除,0未删除,1删除
            algorithmVO.setAlgorithmType(algorithmType);//算法类型
            algorithmVO.setBoxTest(1);//是否通过黑盒测试,0通过,1未通过
            algorithmVO.setAlgorithmExe(algorithmExe);//算法语言
            algorithmVO.setCreateTime(LocalDateTime.now());//算法创建时间
            algorithmVO.setUpdateTime(LocalDateTime.now());//算法更改时间
            util.insert(new PreMappedStatement(util.INSERT,algorithmVO));
        }else {
            //未通过黑盒测试,删除算法
            File file1 = new File(path);
            boolean delete = file1.delete();
        }
    }



    /**
     * 算法使用量+1
     */
    private void hotNumberAdd() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmVO = (AlgorithmVO) util.JSONtoObject(data,AlgorithmVO.class);
        }else {
            algorithmVO=new AlgorithmVO();
        }
        List<Object> query = util.query(new PreMappedStatement(util.QUERY, algorithmVO));
        AlgorithmVO algorithm = (AlgorithmVO) query.get(0);
        Integer hotNumber =algorithm.getHotNumber();
        hotNumber++;
        this.algorithmVO.setHotNumber(hotNumber);
        util.update(new PreMappedStatement(util.UPDATE, algorithmVO));
    }

    /**
     * 预处理算法
     */
    private List<Object> queryHotNumberA() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmHotNumberVO = (AlgorithmHotNumberVO) util.JSONtoObject(data,AlgorithmHotNumberVO.class);
        }else {
            algorithmHotNumberVO=new AlgorithmHotNumberVO();
        }
        algorithmHotNumberVO.setAlgorithmType("预处理算法");
        algorithmHotNumberVO.setAlgorithmDelete(0);//未被删除
        algorithmHotNumberVO.setAlgorithmCheck(0);//审核通过
        algorithmHotNumberVO.setAlgorithmState(0);//私有算法

        List<Object> query = util.query(new PreMappedStatement(util.QUERY, algorithmHotNumberVO));
        AlgorithmHotNumberVO algorithmHotNumberVO1=new AlgorithmHotNumberVO();
        algorithmHotNumberVO1.setAlgorithmState(1);//开源算法
        algorithmHotNumberVO1.setAlgorithmType("预处理算法");
        algorithmHotNumberVO1.setAlgorithmDelete(0);//未被删除
        algorithmHotNumberVO1.setAlgorithmCheck(0);//审核通过
        List<Object> query1 = util.query(new PreMappedStatement(util.QUERY, algorithmHotNumberVO1));

        if(query!=null){
            for(Object o:query){
                query1.add(o);
            }
        }

        return query1;
    }
    /**
     * 建模预处理算法
     */
    private List<Object> queryHotNumberB() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmHotNumberVO = (AlgorithmHotNumberVO) util.JSONtoObject(data,AlgorithmHotNumberVO.class);
        }else {
            algorithmHotNumberVO=new AlgorithmHotNumberVO();
        }
        algorithmHotNumberVO.setAlgorithmType("建模预处理算法");
        algorithmHotNumberVO.setAlgorithmDelete(0);//未被删除
        algorithmHotNumberVO.setAlgorithmCheck(0);//审核通过
        algorithmHotNumberVO.setAlgorithmState(0);//私有算法

        List<Object> query = util.query(new PreMappedStatement(util.QUERY, algorithmHotNumberVO));
        AlgorithmHotNumberVO algorithmHotNumberVO1=new AlgorithmHotNumberVO();
        algorithmHotNumberVO1.setAlgorithmState(1);//开源算法
        algorithmHotNumberVO1.setAlgorithmType("建模预处理算法");
        algorithmHotNumberVO1.setAlgorithmDelete(0);//未被删除
        algorithmHotNumberVO1.setAlgorithmCheck(0);//审核通过
        List<Object> query1 = util.query(new PreMappedStatement(util.QUERY, algorithmHotNumberVO1));

       if(query!=null){
           for(Object o:query){
               query1.add(o);
           }
       }

        return query1;
    }
    /**
     * 建模算法
     */
    private List<Object> queryHotNumberC() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        if(((String)preMappedStatement.getData()).length()>0){
            String data = (String) preMappedStatement.getData();
            algorithmHotNumberVO = (AlgorithmHotNumberVO) util.JSONtoObject(data,AlgorithmHotNumberVO.class);
        }else {
            algorithmHotNumberVO=new AlgorithmHotNumberVO();
        }
        algorithmHotNumberVO.setAlgorithmType("建模算法");
        algorithmHotNumberVO.setAlgorithmDelete(0);//未被删除
        algorithmHotNumberVO.setAlgorithmCheck(0);//审核通过
        algorithmHotNumberVO.setAlgorithmState(0);//私有算法

        List<Object> query = util.query(new PreMappedStatement(util.QUERY, algorithmHotNumberVO));
        AlgorithmHotNumberVO algorithmHotNumberVO1=new AlgorithmHotNumberVO();
        algorithmHotNumberVO1.setAlgorithmState(1);//开源算法
        algorithmHotNumberVO1.setAlgorithmType("建模算法");
        algorithmHotNumberVO1.setAlgorithmDelete(0);//未被删除
        algorithmHotNumberVO1.setAlgorithmCheck(0);//审核通过
        List<Object> query1 = util.query(new PreMappedStatement(util.QUERY, algorithmHotNumberVO1));

        if(query!=null){
            for(Object o:query){
                query1.add(o);
            }
        }

        return query1;
    }





    /**
     * 准备黑盒测试
     * @return
     */
    private boolean testBox(String url,Integer i){//args第一个参数未算法存放路径,第二个为

        Process exec = null;
        try {
            String urll=null;
            String str = url.substring(url.indexOf(".") + 1, url.length());
            if(str.equals("exe")){
                urll=url;
            }else if(str.equals("class")){
                urll="java "+url;
            }else if(str.equals("py")){
                urll="python "+url;
            }else if(str.equals("exe")){
                urll=url;
            }else {
                throw new RuntimeException("没有对应的语言类型算法");
            }

            exec = Runtime.getRuntime().exec(urll);
            // 终端输入参数
            OutputStream outputStream = exec.getOutputStream();
            PrintWriter outputWriter = new PrintWriter(outputStream, true);
            outputWriter.print(i);
            outputWriter.close();
          /*  BufferedReader in = new BufferedReader(new InputStreamReader(exec.getInputStream()));
            String line = null;

            while ((line = in.readLine()) != null) {
            }*/
            // 关闭流文件
           /* in.close();
            try {
                exec.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }


    @Override
    protected boolean insert() {
        return super.insert();
    }

    @Override
    protected List query() {
        return super.query();
    }

    @Override
    protected boolean update() {
        return super.update();
    }

    @Override
    protected boolean delete() {
        return super.delete();
    }
}

